-- UIBineMain
-- Created by chengb Apr/18/2015
-- 魔藤主界面

require "game/ui/form/bine/UIBineSkillLearn"
require "game/ui/form/bine/UIBineSkillUpgrade"
require "game/ui/form/common/UIImproveNotify"

UIBineMain = class("UIBineMain", function()
    return cc.Layer:create();
end);

function UIBineMain.create()
    return UIBineMain.new();
end

-- 模型缩放比例
local MODEL_SCALE = 1.2;

-- 光效缩放比例
local EFFECT_SCALE = 1.5;

function UIBineMain:ctor()
    -- 初始化
    self:setName("UIBineMain");
    local node = cc.CSLoader:createNode("layout/bine/BineMain.csb");
    self:addChild(node);
    self.node = node;

    self:setLocalZOrder(UIMgr.TOP_MENU_ZORDER + 1);

    -- 获取魔藤对象
    self.bine = ME.user.bine;

    -- 注册事件处理回调函数
    self:registerEventCallback()

    -- 注册点击事件
    self:registerTouchEvent();

    -- 初始化窗口
    self:initForm();

    -- 重绘
    self:redraw();

    -- 适配
    self:resize();
end

-- 适配
function UIBineMain:resize()
    local node = self.node;

    -- bg居中显示并充满整个屏幕
    AlignM.fitToScreen(node, "bg");

    -- CT居中并缩放至合适大小
    AlignM.alignToCenter(node, "CT");

    -- BT置于底部并缩放至合适大小
    AlignM.alignToBottomCenter(node, "BT");
end

-- 注册事件处理回调函数
function UIBineMain:registerEventCallback()
    -- 状态刷新
    EventMgr.register("UIBineMain", event.USER_INFO_UPDATED, function(args)
        if args == "clear_prop" then
            self:redrawStatus();
        end
    end);

    -- 注册魔藤升级的事件
    EventMgr.register("UIBineMain", event.BINE_LEVEL_UP, function(args)
        -- 刷新界面
        self:redraw();

        local level = args.level;
        local content = (string.format(getLocStr("bine_level_up"), level));

        -- 显示升级特效界面
        self:showImproveNotify(getLocStr("level_up_title"), content);

        -- 播放升级特效
        self:playBineLevelUpEffect();
    end);

    -- 注册恢复魔藤的事件
    EventMgr.register("UIBineMain", event.CURE_BINE, function(args)
        alert(getLocStr("bine_cure_succ"));

        -- 刷新界面
        self:redraw();

        -- 播放魔藤恢复的光效
        self:playBineCureEffect();
    end);

    -- 注册魔藤复活的事件
    EventMgr.register("UIBineMain", event.BINE_REVIVE, function(args)
        alert(getLocStr("bine_revive_succ"));

        -- 刷新界面
        self:redraw();

        -- 播放魔藤恢复的光效
        self:playBineCureEffect();
    end);

    -- 关注魔藤学习技能事件
    EventMgr.register("UIBineMain", event.BINE_LEARN_SKILL, function(args)
        local function callback()
            -- 重绘界面
            self:redraw();
        end

        -- 学习技能音效
        AudioM.playFx("skill_learn");

        local skillId = args.skillId;

        -- 播放动画
        local child = self:getSkillChild(skillId);
        local iconImg = child:getChildByName("icon");
        local level = SkillM.query(skillId, "level");
        local starNode = findChildByName(child, "star_node");
        playBineSkillUpgradeEffect(iconImg, starNode, callback, 0, 5);

        -- 提示
        local skillName = SkillM.query(skillId, "name");
        local content = string.format(getLocStr("bine_learn_skill_succ"), skillName);
        self:showImproveNotify(getLocStr("gain_skill_title"), content);
    end);

    -- 关注魔藤技能升级技能事件
    EventMgr.register("UIBineMain", event.BINE_UPGRADE_SKILL, function(args)
        -- 显示升级特效界面
        local skillId = args.skillId;
        local skillName = SkillM.query(skillId, "name");
        local level = SkillM.query(skillId, "level") + 1;
        local content = string.format(getLocStr("bine_upgrade_skill_succ"), skillName, level);
        self:showImproveNotify(getLocStr("level_up_title"), content);
    end);

    self:registerScriptHandler(function(eventType)
        if eventType == "exit" then
            cclog("UIBineMain 界面析构清理");

            -- 移除所有事件关注
            EventMgr.removeAll("UIBineMain");

            if UIDungeonMgr:getCurLevel() then
                UIDungeonMgr:getCurLevel():showMenu();
            end

        elseif eventType == "enter" then
            if UIDungeonMgr:getCurLevel() then
                UIDungeonMgr:getCurLevel():hideMenu();
            end
        end
    end);
end

-- 显示能力提升特效界面
function UIBineMain:showImproveNotify(title, content)
    UIMgr.getCurrentScene():removeFormByName("UIImproveNotify");
    local uiNotify = UIImproveNotify.create(title, content);
    UIMgr.getCurrentScene():addForm(uiNotify);
end

-- 注册点击事件
function UIBineMain:registerTouchEvent()
    -- 注册返回按钮点击事件
    local btnBack = findChildByName(self.node, "BT/btn_back");
    local function onBackClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            AudioM.playFx("button_return");
            -- 关闭当前界面
            UIMgr.getCurrentScene():removeFormByName("UIBineMain");
        end
    end
    AddBackEventHandler(self, btnBack, onBackClick);
    TextStyleM.setTextStyle(btnBack, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
    btnBack:setTitleText(getLocStr("btn_text_back"));

    -- 注册升级按钮点击事件
    local btnUpgrade = findChildByName(self.node, "CT/btn_upgrade");
    local function onUpgradeClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            AudioM.playFx("button_click");
            -- 尝试升级
            self:tryLevelUp();
        end
    end
    btnUpgrade:addTouchEventListener(onUpgradeClick);
    TextStyleM.setTextStyle(btnUpgrade, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
    btnUpgrade:setTitleText(getLocStr("btn_text_upgrade"));

    -- 注册恢复按钮点击事件
    local btnRecover = findChildByName(self.node, "CT/btn_recover");
    local function onRecoverClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            AudioM.playFx("button_click");
            -- 如果当前生命值和魔法值都是最大值，无需恢复
            if self.bine:getHp() >= self.bine:getMaxHp() and
               self.bine:getMp() >= self.bine:getMaxMp() then
                alert(getLocStr("no_need_to_cure_bine"));
                return;
            end

            -- 如果摩藤已经死亡
            if self.bine:isDead() then
                -- 尝试复活
                self:tryRevive();
            else
                -- 尝试恢复
                self:tryRecover();
            end
        end
    end
    btnRecover:addTouchEventListener(onRecoverClick);
    TextStyleM.setTextStyle(btnRecover, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
    btnRecover:setTitleText(getLocStr("btn_text_recover"));
end

-- 初始化窗口
function UIBineMain:initForm()
    local skillPanel = findChildByName(self.node, "CT/skill_panel");
    self.skillPanel = skillPanel;

    local panelWidth  = skillPanel:getContentSize().width;
    local panelHeight = skillPanel:getContentSize().height;

    local posY = panelHeight/2;

    local iconWidth  = 94;
    local iconHeight = 94;

    -- 获取所有技能
    local skills = BineM.query(self.bine.classId, "skills");
    local skillNum = #skills;
    if skillNum == 0 then
        return;
    end

    -- 图标与图标直接的间距
    local gap = 25;

    -- 左间距
    local leftWap = 20;

    for i = 1, skillNum do
        local child = cc.CSLoader:createNode("layout/bine/SkillIcon.csb");
        child:setName("skill" .. i);
        local posX = iconWidth / 2 + (i - 1)*(iconWidth + gap) + leftWap;
        child:setPosition(posX, posY);
        skillPanel:addChild(child);

        -- 注册技能框点击事件
        local skillFrame = findChildByName(child, "frame");
        skillFrame:setTouchEnabled(true);
        local function onFrameClick(sender, eventType)
            if eventType == ccui.TouchEventType.ended then
                AudioM.playFx("button_click");
                local skillId = child.skillId;
                if self.bine:ownSkill(skillId) then
                    -- 已学会的技能
                    -- 打开升级界面
                    UIMgr.getCurrentScene():removeFormByName("UIBineSkillUpgrade");
                    local uiForm = UIBineSkillUpgrade.create(skillId);
                    UIMgr.getCurrentScene():addForm(uiForm);
                else
                    -- 打开学习界面
                    UIMgr.getCurrentScene():removeFormByName("UIBineSkillLearn");
                    local uiForm = UIBineSkillLearn.create(skillId);
                    UIMgr.getCurrentScene():addForm(uiForm);
                end
            end
        end
        skillFrame:addTouchEventListener(onFrameClick);
    end

    -- 旋转光圈
    local actionBy = cc.RotateBy:create(30, 360);
    local light = findChildByName(self.node, "CT/left_part/light");
    local sequenceAction = cc.Sequence:create(actionBy);
    light:runAction(cc.RepeatForever:create(sequenceAction));

    -- 初始化光效节点
    local effectNode  = findChildByName(self.node, "CT/left_part/effect_node");
    local effectNode2 = findChildByName(self.node, "CT/left_part/effect_node2");
    effectNode:setScale(EFFECT_SCALE);
    effectNode2:setScale(EFFECT_SCALE);
end

-- 重绘
function UIBineMain:redraw()
    -- 显示标题
    local name = getLocStr("bine_name");
    local titleLabel = findChildByName(self.node, "CT/bg1/bg/title_label");
    titleLabel:setString(name);
    TextStyleM.setArtWordTitleStyle(titleLabel);

    -- 显示魔藤模型
    self:redrawModel();

    -- 显示魔腾属性
    self:redrawAttrib();

    -- 显示魔藤技能
    self:redrawSkill();

    -- 显示升级和恢复的消耗
    self:redrawCost();

    -- 绘制状态图标
    self:redrawStatus();

    -- 重绘按钮
    self:redrawButtons();

    -- 显示底部的说明
    local tipLabel = findChildByName(self.node, "BT/tip");
    local kerning = 0;
    if getLang() ~= "zh" and getLang() ~= "tw" then
        kerning = -1;
    end
    TextStyleM.setTextStyle(tipLabel, TextStyleM.TEXT_SIZE_MIDDLE + kerning, TextStyleM.TEXT_COLOR_BROWN_YELLOW, false, kerning);
    tipLabel:setString(getLocStr("bine_tip2"));
end

-- 显示魔藤模型
function UIBineMain:redrawModel()
    local leftPart = findChildByName(self.node, "CT/left_part");

    -- 显示花园图片
    local gardenImg = findChildByName(leftPart, "garden_icon");
    gardenImg:loadTexture(getLevelItemIconPath("garden2"));

    -- 绘制模型
    local modelNode = findChildByName(leftPart, "model_node");
    modelNode:removeAllChildren();

    local bineDisplay = self:createBineDisplay();
    modelNode:addChild(bineDisplay);

    -- 如果魔藤死亡，花园图片要灰化处理
    if self.bine:isDead() then
        setGrayMode(gardenImg, true);
    else
        setGrayMode(gardenImg, false);
    end

    -- 显示魔藤等级
    local level = self.bine:getLevel();
    local levelLabel = findChildByName(leftPart, "level");
    TextStyleM.setTextStyle(levelLabel, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_ORANGE, true);
    levelLabel:setString(string.format(getLocStr("level_format"), level));
end

-- 显示魔腾属性
function UIBineMain:redrawAttrib()
    local valueLabel, nameLabel;
    local rightPart = findChildByName(self.node, "CT/bg1/right_part");

    local attack = self.bine:getAttack();
    local maxHp  = self.bine:getMaxHp();
    local magic  = self.bine:getMagic();
    local maxMp  = self.bine:getMaxMp();

    -- 攻击
    nameLabel = findChildByName(rightPart, "attack_node/name");
    valueLabel= findChildByName(rightPart, "attack_node/value");
    TextStyleM.setTextStyle(nameLabel, TextStyleM.TEXT_SIZE_SMALL2, TextStyleM.TEXT_COLOR_BEIGE, false, -1);
    TextStyleM.setTextStyle(valueLabel, TextStyleM.TEXT_SIZE_SMALL2, TextStyleM.TEXT_COLOR_BEIGE, false, -1);
    nameLabel:setString(getLocStr("attack"));
    valueLabel:setString(tostring(attack));

    -- 生命
    local nameLabel= findChildByName(rightPart, "hp_node/name");
    local valueLabel= findChildByName(rightPart, "hp_node/value");
    TextStyleM.setTextStyle(nameLabel, TextStyleM.TEXT_SIZE_SMALL2, TextStyleM.TEXT_COLOR_BEIGE, false, -1);
    TextStyleM.setTextStyle(valueLabel, TextStyleM.TEXT_SIZE_SMALL2, TextStyleM.TEXT_COLOR_BEIGE, false, -1);
    nameLabel:setString(getLocStr("hp"));
    local curHp = math.max(0, self.bine:getHp());
    valueLabel:setString(curHp .. "/" .. maxHp);

    -- 魔力
    local nameLabel= findChildByName(rightPart, "dodge_node/name");
    local valueLabel= findChildByName(rightPart, "dodge_node/value");
    local iconImg = findChildByName(rightPart, "dodge_node/icon");
    iconImg:loadTexture(getSmallAttribIconPath("magic"));
    TextStyleM.setTextStyle(nameLabel, TextStyleM.TEXT_SIZE_SMALL2, TextStyleM.TEXT_COLOR_BEIGE, false, -1);
    TextStyleM.setTextStyle(valueLabel, TextStyleM.TEXT_SIZE_SMALL2, TextStyleM.TEXT_COLOR_BEIGE, false, -1);
    nameLabel:setString(getLocStr("magic"));
    valueLabel:setString(tostring(magic));

    -- 魔法
    local nameLabel= findChildByName(rightPart, "accuracy_node/name");
    local valueLabel= findChildByName(rightPart, "accuracy_node/value");
    local iconImg = findChildByName(rightPart, "accuracy_node/icon");
    iconImg:loadTexture(getSmallAttribIconPath("mp"));
    TextStyleM.setTextStyle(nameLabel, TextStyleM.TEXT_SIZE_SMALL2, TextStyleM.TEXT_COLOR_BEIGE, false, -1);
    TextStyleM.setTextStyle(valueLabel, TextStyleM.TEXT_SIZE_SMALL2, TextStyleM.TEXT_COLOR_BEIGE, false, -1);
    nameLabel:setString(getLocStr("mp"));
    valueLabel:setString(self.bine:getMp() .. "/" .. maxMp);

    local addList = {};

    -- 攻击+N效果
    local modelNode = findChildByName(self.node, "CT/left_part/model_node");
    if self.lastAttack ~= nil then
        local addValue =  attack - self.lastAttack;
        table.insert(addList, { "attack", addValue });
    end
    self.lastAttack = attack;

    -- 魔力+N效果
    if self.lastMagic ~= nil then
        local addValue = magic - self.lastMagic;
        table.insert(addList, { "magic", addValue });
    end
    self.lastMagic = magic;

    -- 生命值+N效果
    if self.lastMaxHp ~= nil then
        local addValue = maxHp - self.lastMaxHp;
        table.insert(addList, { "max_hp", addValue });
    end
    self.lastMaxHp = maxHp;

    -- 魔法值+N效果
    if self.lastMaxMp ~= nil then
        local addValue = maxMp - self.lastMaxMp;
        table.insert(addList, { "max_mp", addValue });
    end
    self.lastMaxMp = maxMp;

    -- 播放特效
    for i, arr in pairs(addList) do
        local attrib = arr[1];
        local value  = arr[2];
        if value > 0 then
            local function callFunc()
                playAttribUpEffect(modelNode, value, cc.p(0, 50), attrib);
            end
            performWithDelay(self, callFunc, 2 + 0.5*i);
            i = i + 1;
        end
    end
end

-- 重绘按钮
function UIBineMain:redrawButtons()
    local btnUpgrade = findChildByName(self.node, "CT/btn_upgrade");

    local level = self.bine:getLevel();
    local maxLevel = BineM.query(self.bine.classId, "max_level");

    if level >= maxLevel or
       self.bine:isDead() then
        -- 魔藤已满级或者已经死亡，则升级按钮置灰
        btnUpgrade:setTouchEnabled(false);
        btnUpgrade:setBright(false);
    else
        btnUpgrade:setTouchEnabled(true);
        btnUpgrade:setBright(true);
    end

    local btnRecover = findChildByName(self.node, "CT/btn_recover");
    if self.bine:isDead() then
        -- 魔藤死亡，显示复活
        btnRecover:setTitleText(getLocStr("btn_text_revive"));
    else
        -- 未死亡，显示恢复
        btnRecover:setTitleText(getLocStr("btn_text_recover"));
    end
end

-- 获取技能框控件
function UIBineMain:getSkillChild(skillId)
    -- 获取所有技能
    local skills = BineM.query(self.bine.classId, "skills");
    local skillNum = #skills;
    for i = 1, #skills do
        local child = findChildByName(self.skillPanel, "skill" .. i);
        if SkillM.findBaseSkill(child.skillId) == SkillM.findBaseSkill(skillId) then
        	return child;
        end
    end

    return nil;
end

-- 显示魔藤技能
function UIBineMain:redrawSkill()
    -- 获取所有技能
    local skills = BineM.query(self.bine.classId, "skills");

    local skillNum = #skills;
    if skillNum == 0 then
        return;
    end

    local learnedSkills = self.bine:getAllSkills();

    for i, skillId in pairs(skills) do
        local child    = findChildByName(self.skillPanel, "skill" .. i);
        local iconImg  = findChildByName(child, "icon");
        local starNode = findChildByName(child, "star_node");
        local frame    = findChildByName(child, "frame");

        local skillInfo = SkillM.query(skillId);

        -- 绘制技能图标
        iconImg:loadTexture(getSkillIconPath(skillInfo["icon"]));

        setGrayMode(iconImg, false);

        -- 如果该技能已学习
        if self.bine:ownSkill(skillId) then
            -- 获取技能等级，并根据等级获取对应的技能编号
            local level = self.bine:getSkillLevel(skillId);
            child.skillId = SkillM.findSkill(skillId, level);

            -- 绘制技能星级
            local lightStarPath = "images/ui/symbol/career_star_01.png";
            local layer = createStarLayer(level, lightStarPath, "center", -0.5, 0.825);

            if layer then
                starNode:removeAllChildren();
                starNode:addChild(layer);
            end
            setGrayMode(iconImg, false);

            frame:setOpacity(255);
        else
            child.skillId = skillId;

            -- 未学习的技能图标需要灰化处理
            setGrayMode(iconImg, false);
            setGrayMode(iconImg, true);

            -- 框需要半透明
            frame:setOpacity(100);
        end

        -- 如果满足学习或升级的条件，则显示加号蒙版
        if true == BineM.canLearnSkill(child.skillId) then
            -- 可学习
            -- 播放气泡动画
            playBubbleAnima(iconImg, false);
        elseif true == BineM.canUpgradeSkill(child.skillId) then
            -- 可升级
            -- 播放气泡动画
            playBubbleAnima(iconImg, false);
        else
            iconImg:stopAllActions();
        end
    end
end

-- 显示消耗
function UIBineMain:redrawCost()
    local tipLabel = findChildByName(self.node, "CT/tip");
    TextStyleM.setTextStyle(tipLabel, TextStyleM.TEXT_SIZE_SMALL, TextStyleM.TEXT_COLOR_DARK_BROWN);
    tipLabel:setString(getLocStr("bine_tip"));

    -- 升级消耗
    local upgradeCost = FormulaM.invoke("CALC_BINE_COST", "level_up");
    local classId = table.keys(upgradeCost)[1];
    local amount  = table.values(upgradeCost)[1];
    local curAmount = ItemM.getAmount(ME.user, classId);

    local priceLabel = findChildByName(self.node, "CT/upgrade_price_node/price");
    local iconImg = findChildByName(self.node, "CT/upgrade_price_node/icon");
    local icon = ItemM.query(classId, "icon");

    -- 消耗不足时，红色显示
    if ItemM.getAmount(ME.user, classId) < amount then
        TextStyleM.setTextStyle(priceLabel, TextStyleM.TEXT_SIZE_SMALL, TextStyleM.TEXT_COLOR_DARK_RED, false);
    else
        TextStyleM.setTextStyle(priceLabel, TextStyleM.TEXT_SIZE_SMALL, TextStyleM.TEXT_COLOR_BEIGE, false);
    end
    priceLabel:setString(curAmount .. "/" .. amount);

    iconImg:loadTexture(getItemIconPath(icon));
    iconImg:setScale(0.6);
    iconImg:setPositionY(0);

    local cureCost;
    local dead = self.bine:isDead();
    if dead then
        -- 如果魔藤已经死亡
        -- 复活消耗
        cureCost = FormulaM.invoke("CALC_BINE_COST", "revive");
    else
        -- 治疗消耗
        cureCost = FormulaM.invoke("CALC_BINE_COST", "cure");
    end

    local classId = table.keys(cureCost)[1];
    local amount  = table.values(cureCost)[1];
    local curAmount = ItemM.getAmount(ME.user, classId);

    -- 消耗不足时，红色显示
    local priceLabel = findChildByName(self.node, "CT/recover_price_node/price");
    local iconImg = findChildByName(self.node, "CT/recover_price_node/icon");
    local icon = ItemM.query(classId, "icon");
    iconImg:loadTexture(getItemIconPath(icon));

    if ItemM.getAmount(ME.user, classId) < amount then
        TextStyleM.setTextStyle(priceLabel, TextStyleM.TEXT_SIZE_SMALL, TextStyleM.TEXT_COLOR_DARK_RED, false);
    else
        TextStyleM.setTextStyle(priceLabel, TextStyleM.TEXT_SIZE_SMALL, TextStyleM.TEXT_COLOR_BEIGE, false);
    end
    priceLabel:setString(curAmount .. "/" .. amount);

    iconImg:setScale(0.6);
    iconImg:setPositionY(0);
end

-- 显示状态
function UIBineMain:redrawStatus()
    -- 增益状态
    local statusNode = findChildByName(self.node, "CT/left_part/status_node");
    local buff = PropM.getBuff(ME.user.bine);
    local gainImage = statusNode:getChildByName("gain_buff");
    if #buff <= 0 then
        gainImage:setVisible(false);
    else
        gainImage:loadTexture(getStatusIconPath(PropM.getPropIcon(buff[1])));
        gainImage.propId = buff[1][1];
        gainImage.effect = PropM.getPropDesc(buff[1]);
        gainImage.round = buff[1][4];
        gainImage.name = "";
    end

    -- 减益状态
    local deBuff = PropM.getDebuff(ME.user.bine);
    local debuffsImage = statusNode:getChildByName("debuff");
    if #deBuff <= 0 then
        debuffsImage:setVisible(false);
    else
        debuffsImage:loadTexture(getStatusIconPath(PropM.getPropIcon(deBuff[1])));
        debuffsImage.propId = deBuff[1][1];
        debuffsImage.effect = PropM.getPropDesc(deBuff[1]);
        debuffsImage.round = deBuff[1][4];
        debuffsImage.name = "";
    end

    -- 特殊状态
    local specials = PropM.getSpecialProp(ME.user.bine);
    local specialImage = statusNode:getChildByName("special_buff");
    if #specials <= 0 then
        specialImage:setVisible(false);
    else
        specialImage:loadTexture(getStatusIconPath(PropM.getPropIcon(specials[1])));
        specialImage.propId = specials[1][1];
        specialImage.effect = PropM.getPropDesc(specials[1]);
        specialImage.round = specials[1][4];
        specialImage.name = "";
    end

    -- 定时刷新状态
    performWithDelay(self, function() self:refreshStatus(); end, 1);
end

-- 刷新状态显示
function UIBineMain:refreshStatus()
    -- 特殊
    local specials = PropM.getSpecialProp(ME.user);
    local statusNode = findChildByName(self.node, "CT/left_part/status_node");
    local specialImage = statusNode:getChildByName("special_buff");
    if #specials > 1 then
        for i = 1, #specials do
            if specialImage.propId ~= specials[i][1] then
                specialImage:loadTexture(getStatusIconPath(PropM.getPropIcon(specials[i])));
                specialImage.propId = specials[i][1];
                specialImage.effect = PropM.getPropDesc(specials[i]);
                specialImage.round = specials[i][4];
                specialImage.name = "";
                break;
            end
        end

        -- 定时刷新状态
        performWithDelay(self, function() self:refreshStatus(); end, 1);
    end
end

-- 尝试升级
function UIBineMain:tryLevelUp()
    local upgradeCost = FormulaM.invoke("CALC_BINE_COST", "level_up");
    local classId   = table.keys(upgradeCost)[1];
    local amount    = table.values(upgradeCost)[1];
    local name      = ItemM.query(classId, "name");
    local unit      = ItemM.query(classId, "unit");
    local curAmount = ItemM.getAmount(ME.user, classId);

    local function tryLevelUp()
        -- 判断能否升级
        local ret = BineM.canLevelUp();
        if ret ~= true then
            if ret == "cost_lack" then
                alert(string.format(getLocStr("item_not_enough2"), name));
            else
                trace("UIBineMain", "无法升级魔藤，原因：%s", tostring(ret));
            end
            return;
        end

        -- 升级
        DungeonActionM.go("bine_level_up")
    end

    -- 确认提示
    local nextLevel = self.bine:getLevel() + 1;
    local msg = string.format(getLocStr("bine_level_up_confirm"), amount, unit, name, nextLevel);
    if curAmount < amount then
        -- 数量不足，显示红色
        msg = msg .. string.format(getLocStr("own_item_format2"), name, curAmount, amount);
    else
        msg = msg .. string.format(getLocStr("own_item_format1"), name, curAmount, amount);
    end

    confirm2(CONFIRM_TYPE_OK, getLocStr("bine_cultivate_title"), msg,
        tryLevelUp, nil, getLocStr("btn_text_upgrade"));
end

-- 尝试恢复
function UIBineMain:tryRecover()
    -- 恢复消耗
    local cureCost  = FormulaM.invoke("CALC_BINE_COST", "cure");

    local classId   = table.keys(cureCost)[1];
    local amount    = table.values(cureCost)[1];
    local name      = ItemM.query(classId, "name");
    local unit      = ItemM.query(classId, "unit");
    local curAmount = ItemM.getAmount(ME.user, classId);

    -- 尝试恢复
    local function tryCure()
        -- 判断能否恢复
        local ret = BineM.canCure();
        if ret ~= true then
            if ret == "cost_lack" then
                alert(string.format(getLocStr("item_not_enough2"), name));
            elseif ret == "bine_dead" then
                alert(getLocStr("cannot_cure_dead_bine"));
            else
                trace("UIBineMain", "无法恢复魔藤，原因：%s", tostring(ret));
            end

            return;
        end

        -- 恢复魔藤
        DungeonActionM.go('bine_cure')
    end

    -- 确认提示
    local cureValue = FormulaM.invoke("CALC_BINE_CURE_RECOVER")["hp"];
    local msg = string.format(getLocStr("bine_cure_confirm"), amount, unit, name, cureValue);
    if curAmount < amount then
        -- 数量不足，显示红色
        msg = msg .. string.format(getLocStr("own_item_format2"), name, curAmount, amount);
    else
        msg = msg .. string.format(getLocStr("own_item_format1"), name, curAmount, amount);
    end

    confirm2(CONFIRM_TYPE_OK, getLocStr("bine_cultivate_title"), msg,
        tryCure, nil, getLocStr("btn_text_recover"));
end

-- 尝试复活
function UIBineMain:tryRevive()
    -- 复活消耗
    local reviveCost  = FormulaM.invoke("CALC_BINE_COST", "revive");

    local classId   = table.keys(reviveCost)[1];
    local amount    = table.values(reviveCost)[1];
    local name      = ItemM.query(classId, "name");
    local unit      = ItemM.query(classId, "unit");
    local curAmount = ItemM.getAmount(ME.user, classId);

    -- 尝试复活
    local function tryRevive()
        -- 判断能否复活
        local ret = BineM.canRevive();
        if ret ~= true then
            if ret == "cost_lack" then
                alert(string.format(getLocStr("item_not_enough"), name));
            elseif ret == "bine_dead" then
                alert(getLocStr("cannot_cure_dead_bine"));
            else
                trace("UIBineMain", "无法复活魔藤，原因：%s", tostring(ret));
            end

            return;
        end

        -- 复活魔藤
        DungeonActionM.go("bine_revive");
    end

    local cureValue = BineM.calcReviveHp(ME.user.bine);

    -- 确认提示
    local msg = string.format(getLocStr("bine_revive_confirm"), amount, unit, name, cureValue);
    if curAmount < amount then
        -- 数量不足，显示红色
        msg = msg .. string.format(getLocStr("own_item_format2"), name, curAmount, amount);
    else
        msg = msg .. string.format(getLocStr("own_item_format1"), name, curAmount, amount);
    end

    confirm2(CONFIRM_TYPE_OK, getLocStr("bine_cultivate_title"), msg,
        tryRevive, nil, getLocStr("btn_text_revive"));
end

-- 创建魔藤模型
function UIBineMain:createBineDisplay()
    -- 创建模型
    local bine = ME.user.bine;
    local classId = bine.classId;
    local bineDisplay = BineDisplay.create(classId);

    -- 设置缩放比例
    bineDisplay:setScale(MODEL_SCALE);

    -- 设置偏移量
    local offsetX = 130;
    local offsetY = 875;

    bineDisplay:setPosition(tonumber(offsetX), tonumber(offsetY));
    return bineDisplay;
end

-- 播放魔藤升级光效
function UIBineMain:playBineLevelUpEffect()
    local effectNode  = findChildByName(self.node, "CT/left_part/effect_node");
    local effectNode2 = findChildByName(self.node, "CT/left_part/effect_node2");
    effectNode:removeAllChildren();
    effectNode2:removeAllChildren();

    playEffect(effectNode, 1147);
    playEffect(effectNode2, 1148);
end

-- 播放魔藤恢复/复活的光效
function UIBineMain:playBineCureEffect()
    local effectNode  = findChildByName(self.node, "CT/left_part/effect_node");
    local effectNode2 = findChildByName(self.node, "CT/left_part/effect_node2");
    effectNode:removeAllChildren();
    effectNode2:removeAllChildren();

    playEffect(effectNode, 1149);
    playEffect(effectNode2, 1150);
end